package com.shhm.common.aspect;

import com.shhm.common.annotations.OperateLog;
import com.shhm.common.entity.system.SysLog;
import com.shhm.common.service.LogService;
import com.shhm.common.utils.IpUtil;
import com.shhm.common.utils.JwtUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * @author JackZ
 * @version 1.0
 * @description: TODO
 * @date 2025/8/5 下午3:22
 */
@Component
@Aspect
public class OperateLogAspect {
    @Resource
    private LogService logService;

    @Pointcut("@annotation(com.shhm.common.annotations.OperateLog)")
    public void operateLogPointCut(){}

    @Around("operateLogPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
//        获取并处理数据
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .currentRequestAttributes())
                .getRequest();
        String auth = request.getHeader("Authorization");
        String token = JwtUtil.handleAuthorizationString(auth);
        String realName = JwtUtil.getRealNameFromToken(token);
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        OperateLog operateLog = method.getAnnotation(OperateLog.class);
//        创建实体类
        SysLog log = new SysLog();
        log.setUserId(JwtUtil.getUIDFromToken(token));
        log.setRealName(JwtUtil.getRealNameFromToken(token));
        log.setOpearateType(operateLog.type());
        log.setOperateModule(operateLog.module());
        log.setDescription(operateLog.desc());
        log.setRealName(realName);
        log.setOperateTime(LocalDateTime.now());
        log.setOperateIp(IpUtil.getIpAddress(request));
        try {
            Object res = joinPoint.proceed();
            log.setStatus(1);
            saveLog(log);
            return res;
        }catch (Exception e){
            log.setStatus(0);
            log.setDescription("系统异常:"+e.getMessage());
            saveLog(log);
            throw e;
        }
    }

    @Async
    protected void saveLog(SysLog sysLog){
        logService.save(sysLog);
    }
}
